package topic

import (
	"context"
	"strconv"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/types/forum"

	"github.com/volatiletech/null/v8"
	"github.com/zeromicro/go-zero/core/logx"
)

type CreateTopicLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCreateTopicLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateTopicLogic {
	return &CreateTopicLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *CreateTopicLogic) CreateTopic(in *forum.TopicInfo) (*forum.BaseIDResp, error) {
	if in.Title == nil || len(strings.TrimSpace(*in.Title)) == 0 {
		return nil, resultx.StatusError(resultx.FORUM_TOPIC_TITLE_REQUIRED, "")
	}

	title := strings.TrimSpace(*in.Title)

	if in.Author == nil || in.Author.Id == nil || *in.Author.Id == 0 {
		return nil, resultx.StatusError(resultx.FORUM_TOPIC_AUTHOR_ID_INVALID, "")
	}

	userId := *in.Author.Id
	now := time.Now() // 本地时间
	gmtNow := modelx.GetGmtTime(now)
	topic := &model.ForumTopic{
		TopicAuthorID:     userId,
		Title:             title,
		TopicDate:         now,
		TopicDateGMT:      gmtNow,
		TopicModifiedDate: now,
		TopicModifiedGMT:  gmtNow,
		TopicStatus:       uint8(globalkey.StatusPending),
	}
	if in.ForumId != nil && *in.ForumId > 0 {
		topic.ForumID = *in.ForumId
	}
	if in.Slug != nil && len(*in.Slug) > 0 {
		topic.Slug = strings.TrimSpace(*in.Slug)
	}

	if in.Author.Name != nil {
		topic.TopicAuthorNickname = *in.Author.Name
	}
	if in.Author.Email != nil {
		topic.TopicAuthorEmail = *in.Author.Email
	}
	if in.Author.Avatar != nil {
		topic.TopicAuthorAvatar = *in.Author.Avatar
	}
	if in.Author.Ip != nil {
		topic.TopicAuthorIP = *in.Author.Ip
	}
	if in.Author.Level != nil {
		topic.TopicAuthorRankID = uint8(*in.Author.Level)
	}
	if in.Author.Anonymous != nil {
		topic.TopicAuthorAnonymous = uint8(*in.Author.Anonymous)
	}

	rel := &model.ForumTopicRel{}
	if in.ContentHtml != nil && len(strings.TrimSpace(*in.ContentHtml)) > 0 {
		rel.Post = &model.ForumPost{
			PostAuthorID:        userId,
			PostContent:         strings.TrimSpace(*in.ContentHtml),
			PostDate:            now,
			PostDateGMT:         gmtNow,
			PostModifiedDate:    now,
			PostModifiedGMT:     gmtNow,
			PostStatus:          uint8(globalkey.StatusPending),
			ForumID:             topic.ForumID,
			PostAuthorNickname:  topic.TopicAuthorNickname,
			PostAuthorEmail:     topic.TopicAuthorEmail,
			PostAuthorAvatar:    topic.TopicAuthorAvatar,
			PostAuthorIP:        topic.TopicAuthorIP,
			PostAuthorAnonymous: topic.TopicAuthorAnonymous,
		}
		if in.CommentStatus != nil {
			rel.Post.CommentStatus = uint8(*in.CommentStatus)
		}
	}

	if len(in.Meta) > 0 {
		for _, v := range in.Meta {
			if v.Key == nil || v.Value == nil || len(strings.TrimSpace(*v.Key)) == 0 || len(strings.TrimSpace(*v.Value)) == 0 {
				continue
			}

			rel.Meta = append(rel.Meta, &model.ForumTopicMetum{
				MetaKey:   strings.TrimSpace(*v.Key),
				MetaValue: null.StringFrom(strings.TrimSpace(*v.Value)),
			})
		}
	}

	var thumbnailId uint64
	var thumbnailUrl string
	if len(in.NewMedia) > 0 {
		for _, v := range in.NewMedia {
			var url string
			if v.Url != nil && len(*v.Url) > 0 { // 最终网址
				url = *v.Url
			}
			if len(url) == 0 && v.Uri != nil && len(*v.Uri) > 0 { // 临时网址
				url = *v.Uri
			}
			if len(url) == 0 {
				continue
			}

			var media model.ForumAttachmentRelationship
			if v.Id != nil && len(*v.Id) > 0 {
				if i, err := strconv.ParseInt(*v.Id, 10, 64); err == nil && i > 0 {
					media.AttachmentID = uint64(i)
					if len(thumbnailUrl) == 0 && thumbnailId == 0 {
						thumbnailId = uint64(i)
					}
				}
			}
			if len(thumbnailUrl) == 0 {
				thumbnailUrl = url
			}
			if v.Uri != nil && len(*v.Uri) > 0 {
				media.AttachmentSource = *v.Uri
			}
			media.AttachmentImageURL = url
			if v.Thumbnail != nil && *v.Thumbnail > 0 {
				media.AttachmentThumbnail = uint8(*v.Thumbnail)
			}
			if v.AltText != nil && len(*v.AltText) > 0 {
				media.AttachmentImageAlt = *v.AltText
			}
			if v.Meta != nil && len(*v.Meta) > 0 {
				media.AttachmentImageMeta = *v.Meta
			}
			if v.Order != nil && *v.Order > 0 {
				media.AttachmentOrder = uint(*v.Order)
			}
			rel.Media = append(rel.Media, &media)
		}
	}

	if topic.TopicAuthorAnonymous == 0 {
		rel.Feed = &model.ForumFeed{
			ForumID:        topic.ForumID,
			TopicID:        topic.TopicID,
			AuthorID:       topic.TopicAuthorID,
			AuthorNickname: topic.TopicAuthorNickname,
			AuthorAvatar:   topic.TopicAuthorAvatar,
			AuthorIP:       topic.TopicAuthorIP,
			AuthorRankID:   topic.TopicAuthorRankID,
			Excerpt:        title,
			ThumbnailID:    thumbnailId,
			ThumbnailURL:   thumbnailUrl,
			Status:         uint8(globalkey.StatusPending),
		}
	}

	tx, err := l.svcCtx.DB.BeginTx(l.ctx, nil)
	if err != nil {
		return nil, resultx.StatusError(resultx.DB_ERROR, "")
	}

	err = l.svcCtx.Topic.Insert(l.ctx, tx, topic, rel)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	tx.Commit()

	return &forum.BaseIDResp{
		Id: topic.TopicID,
	}, nil
}
